package kevin.ecstorm.pdd.service.impl;

import com.pdd.pop.sdk.http.PopAccessTokenClient;
import com.pdd.pop.sdk.http.PopBaseHttpRequest;
import com.pdd.pop.sdk.http.PopBaseHttpResponse;
import com.pdd.pop.sdk.http.PopHttpClient;
import com.pdd.pop.sdk.http.token.AccessTokenResponse;
import kevin.ecstorm.pdd.config.PddAppAuth;
import kevin.ecstorm.pdd.constants.ExceptionCode;
import kevin.ecstorm.pdd.service.IPddService;
import kevin.framework.core.exception.BusinessException;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * ©Copyright ©1968-2020 Midea Group,IT
 * FileName: EcstormPddServiceImpl
 * Author: kevin
 * Date: 2020年03月05日 23:58:35
 * Description: EcstormPddServiceImpl服务接口
 */
@Service
public class PddServiceImpl implements IPddService {
    private Map<String, PopHttpClient> clients = new HashMap<>();

    @Override
    public <T extends PopBaseHttpResponse> T syncInvoke(PopBaseHttpRequest<T> popBaseHttpRequest, PddAppAuth auth) {
        PopHttpClient client = getClient(auth.getClientId(), auth.getClientSecret());
        if (auth.getAccessToken() == null) {
            AccessTokenResponse accessTokenResponse = this.generate(auth.getClientId(), auth.getClientSecret(), auth.getCode());
            auth.setAccessToken(accessTokenResponse.getAccessToken());
        }
        try {
            T resp = client.syncInvoke(popBaseHttpRequest, auth.getAccessToken());
            if (resp.getErrorResponse() != null) {
                if (resp.getErrorResponse().getErrorCode() == 10019) {
                    AccessTokenResponse accessTokenResponse = this.refreshAccessToken(auth.getClientId(), auth.getClientSecret(), auth.getRefreshToken());
                    if (accessTokenResponse.getErrorResponse() != null) {
                        throw new BusinessException(accessTokenResponse.getErrorResponse().getErrorMsg());
                    }
                    auth.setAccessToken(accessTokenResponse.getAccessToken());
                    resp = client.syncInvoke(popBaseHttpRequest, auth.getAccessToken());
                    if (resp.getErrorResponse() != null) {
                        throw new BusinessException(resp.getErrorResponse().getErrorMsg());
                    }
                }
            }
            return resp;
        } catch (Exception e) {
            throw new BusinessException(ExceptionCode.PDD_INTERFACE_ERR, e);
        }
    }


    @Override
    public PopHttpClient getClient(String clientId, String clientSecret) {
        try {
            PopHttpClient client = clients.get(clientId);
            if (client == null) {
                synchronized (this) {
                    client = new PopHttpClient(clientId, clientSecret);
                }
            }
            return client;
        } catch (Exception e) {
            throw new BusinessException(ExceptionCode.PDD_INTERFACE_ERR, e);
        }
    }

    private AccessTokenResponse generate(String clientId, String clientSecret, String code) {
        try {
            PopAccessTokenClient accessTokenClient = new PopAccessTokenClient(clientId, clientSecret);
            return accessTokenClient.generate(code);
        } catch (Exception e) {
            throw new BusinessException(ExceptionCode.PDD_INTERFACE_ERR, e);
        }
    }

    private AccessTokenResponse refreshAccessToken(String clientId, String clientSecret, String refreshToken) {
        try {
            PopAccessTokenClient accessTokenClient = new PopAccessTokenClient(clientId, clientSecret);
            return accessTokenClient.refresh(refreshToken);
        } catch (Exception e) {
            throw new BusinessException(ExceptionCode.PDD_INTERFACE_ERR, e);
        }
    }
}
